/**

 * Copyright 2014-2015 www.fsfkj.com
 * All rights reserved.
 * 
 * @project
 * @author Flouny.Caesar
 * @version 1.0
 * @date 2015-10-20
 */
package com.eyaomall.wxmall.common.initial;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.eyaomall.wxmall.common.helper.OcsHelper;
import com.eyaomall.wxmall.common.util.EhCacheUtil;
import com.eyaomall.wxmall.model.po.Area;
import com.eyaomall.wxmall.service.AreaService;
import com.lycheeframework.core.common.helper.GlobEnv;
import com.lycheeframework.core.common.util.ListUtil;
import com.lycheeframework.core.common.util.MapUtil;

@Service
public class AreaInitial implements BeanFactoryAware {
	
	@Autowired
	private AreaService areaService;
	
	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		initAreas();
		initAreaByAreaKey();
		initAreaByID();
		initCascadeArea();
		initCountySubDistrictByCityId();
	}
	
	/**
	 * 重新加载缓存
	 */
	public void reload(){
		initAreas();
		initAreaByAreaKey();
		initAreaByID();
		initCascadeArea();
		initCountySubDistrictByCityId();
	}
	/**
	 * 初始化所有区域
	 */
	private void initAreas() {
		List<Area> areas = areaService.getAreas();
		if (ListUtil.isEmpty(areas)) return;
		
		Map<Integer, Area> areasMap = new HashMap<Integer, Area>();
		for (Area area: areas) {
			areasMap.put(area.getId(), area);
		}
		
		EhCacheUtil.put("areasMap", areasMap);
		EhCacheUtil.put("areas", areas);
		
		if ("n".equalsIgnoreCase(GlobEnv.get("ocs.locked"))) {
			OcsHelper.set("areasMap", areasMap);
			OcsHelper.set("areas", areas);
		}
	}
	
	/**
	 * 初始化省、市、区、商圈
	 */
	@SuppressWarnings("unchecked")
	private void initAreaByAreaKey() {
		String[] areaKeyName = {"AREA.PROVINCE", "AREA.CITY", "AREA.COUNTY", "AREA.DISTRICT"};
		List<Area> areas = (List<Area>) EhCacheUtil.get("areas");
		if (ListUtil.isEmpty(areas)) return;
		
		for (int i = 0; i < areaKeyName.length; i++) {
			List<Area> areaList = new ArrayList<Area>();
			for (Area area: areas) {
				if (!areaKeyName[i].equals(area.getAreaKey())) continue;
				
				areaList.add(area);
			}
			
			if (ListUtil.isEmpty(areaList)) continue;
			
			EhCacheUtil.put((areaKeyName[i] + "S").toLowerCase(), areaList);
			
			if ("n".equalsIgnoreCase(GlobEnv.get("ocs.locked"))) {
				OcsHelper.set((areaKeyName[i] + "S").toLowerCase(), areaList);
			}
		}
	}
	
	/**
	 * 初始化，根据parentId获取下联的数据，只针对一级
	 */
	@SuppressWarnings("unchecked")
	private void initAreaByID() {
		List<Area> areas = (List<Area>) EhCacheUtil.get("areas");
		if (ListUtil.isEmpty(areas)) return;
		
		Map<Integer, List<Area>> areasMap = new HashMap<Integer, List<Area>>();
		for (Area area: areas) {
			List<Area> areaList = new ArrayList<Area>();
			for (Area areaChild: areas) {
				if (area.getId().intValue() != areaChild.getParentId().intValue()) continue;
				
				areaList.add(areaChild);
			}
			
			areasMap.put(area.getId(), areaList);
		}
		
		EhCacheUtil.put("areaByID", areasMap);
		
		if ("n".equalsIgnoreCase(GlobEnv.get("ocs.locked"))) {
			OcsHelper.set("areaByID", areasMap);
		}
	}
	
	/**
	 * 根据城市ID，初始化区域及商圈级联数据
	 */
	@SuppressWarnings("unchecked")
	private void initCountySubDistrictByCityId() {
		List<Area> citys = (List<Area>) EhCacheUtil.get("area.citys");
		if (ListUtil.isEmpty(citys)) return;
		
		Map<Integer, List<Area>> areasMap = (Map<Integer, List<Area>>) EhCacheUtil.get("areaByID");
		if (MapUtil.isEmpty(areasMap)) return;
		
		Map<Integer, List<Map<String, Object>>> cityMap = new HashMap<Integer, List<Map<String, Object>>>();
		for (Area city: citys) {
			List<Area> countys = areasMap.get(city.getId().intValue());
			if (ListUtil.isEmpty(countys)) continue;
			
			List<Map<String, Object>> countyList = new ArrayList<Map<String, Object>>();
			for (Area county: countys) {
				List<Area> districts = areasMap.get(county.getId().intValue());
				if (ListUtil.isEmpty(districts)) continue;
				
				Map<String, Object> countyObject = new HashMap<String, Object>();
				countyObject.put("id", county.getId().intValue());
				countyObject.put("areaKey", county.getAreaKey());
				countyObject.put("areaName", county.getAreaName());
				countyObject.put("parentId", county.getParentId());
				
				List<Map<String, Object>> districtList = new ArrayList<Map<String, Object>>();
				for (Area district: districts) {
					Map<String, Object> districtObject = new HashMap<String, Object>();
					districtObject.put("id", district.getId().intValue());
					districtObject.put("areaKey", district.getAreaKey());
					districtObject.put("areaName", district.getAreaName());
					districtObject.put("parentId", district.getParentId());
					
					districtList.add(districtObject);
				}
				
				if (ListUtil.isNotEmpty(districtList)) 
					countyObject.put("children", districtList);
				
				countyList.add(countyObject);
			}
			
			cityMap.put(city.getId(), countyList);
		}
		
		EhCacheUtil.put("countySubDistrictByCityIdMap", cityMap);
		
		if ("n".equalsIgnoreCase(GlobEnv.get("ocs.locked"))) {
			OcsHelper.set("countySubDistrictByCityIdMap", cityMap);
		}
	}
	
	/**
	 * 初始化区域级联数据
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void initCascadeArea() {
		List<Area> provinces = (List<Area>) EhCacheUtil.get("area.provinces");
		if (ListUtil.isEmpty(provinces)) return;
		
		List provinceList = new ArrayList();
		for (Area province: provinces) {
			Map provinceObject = new HashMap();
			provinceObject.put("id", province.getId());
			provinceObject.put("areaKey", province.getAreaKey());
			provinceObject.put("areaName", province.getAreaName());
			
			List cityList = new ArrayList();
			List<Area> citys = (List<Area>) EhCacheUtil.get("area.citys");
			if (ListUtil.isEmpty(citys)) continue;
			for (Area city: citys) {
				if (province.getId().intValue() != city.getParentId().intValue()) continue;
				Map<String, Object> cityObject = new HashMap<String, Object>();
				cityObject.put("id", city.getId());
				cityObject.put("areaKey", city.getAreaKey());
				cityObject.put("areaName", city.getAreaName());
				cityObject.put("parentId", city.getParentId());
				
				List<Map<String, Object>> countyList = new ArrayList<Map<String, Object>>();
				List<Area> countys = (List<Area>) EhCacheUtil.get("area.countys");
				if (ListUtil.isEmpty(countys)) continue;
				for (Area county: countys) {
					if (city.getId().intValue() != county.getParentId().intValue()) continue;
					
					Map<String, Object> countyObject = new HashMap<String, Object>();
					countyObject.put("id", county.getId());
					countyObject.put("areaKey", county.getAreaKey());
					countyObject.put("areaName", county.getAreaName());
					countyObject.put("parentId", county.getParentId());
					
					List<Map<String, Object>> districtList = new ArrayList<Map<String, Object>>();
					List<Area> districts = (List<Area>) EhCacheUtil.get("area.districts");
					if (ListUtil.isEmpty(districts)) continue;
					for (Area district: districts) {
						if (county.getId().intValue() != district.getParentId().intValue()) continue;
						
						Map<String, Object> districtObject = new HashMap<String, Object>();
						districtObject.put("id", district.getId());
						districtObject.put("areaKey", district.getAreaKey());
						districtObject.put("areaName", district.getAreaName());
						districtObject.put("parentId", district.getParentId());
						
						districtList.add(districtObject);
					}
					
					if (ListUtil.isNotEmpty(districtList)) 
						countyObject.put("children", districtList);
					
					countyList.add(countyObject);
				}
				if (ListUtil.isNotEmpty(countyList)) 
					cityObject.put("children", countyList);
				
				cityList.add(cityObject);
			}
			
			if (ListUtil.isNotEmpty(cityList)) 
				provinceObject.put("children", cityList);
			
			provinceList.add(provinceObject);
		}
		
		if (ListUtil.isEmpty(provinceList)) return;
		EhCacheUtil.put("cascadeArea", provinceList);
		
		if ("n".equalsIgnoreCase(GlobEnv.get("ocs.locked"))) {
			OcsHelper.set("cascadeArea", provinceList);
		}
	}
}